package com.aquarium.alarm;

import java.util.HashMap;
import java.util.Observable;

import com.aquarium.bt.RecvDataDispatcher;
import com.aquarium.config.AlarmDefaultValue;
import com.aquarium.data.LocalDataManager;
import com.aquarium.ui.SensorValueDisplayActivity;
import com.aquarium.util.SPUtils;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class AlarmManager extends Observable {

	public final static String GET_PH_MIN_KEY = "GET_PH_MIN_KEY";
	public final static String GET_PH_MAX_KEY = "GET_PH_MAX_KEY";
	public final static String GET_PH_INTERVAL_KEY = "GET_PH_INTERVAL_KEY";
	public final static String GET_TEMPERATURE_MIN_KEY = "GET_TEMPERATURE_MIN_KEY";
	public final static String GET_TEMPERATURE_MAX_KEY = "GET_TEMPERATURE_MAX_KEY";
	public final static String GET_TEMPERATURE_INTERVAL_KEY = "GET_TEMPERATURE_INTERVAL_KEY";
	public final static String GET_OXYGEN_MIN_KEY = "GET_OXYGEN_MIN_KEY";
	public final static String GET_OXYGEN_MAX_KEY = "GET_OXYGEN_MAX_KEY";
	public final static String GET_OXYGEN_INTERVAL_KEY = "GET_OXYGEN_INTERVAL_KEY";
	public final static String GET_CONDUCTIVITY_MIN_KEY = "GET_CONDUCTIVITY_MIN_KEY";
	public final static String GET_CONDUCTIVITY_MAX_KEY = "GET_CONDUCTIVITY_MAX_KEY";
	public final static String GET_CONDUCTIVITY_INTERVAL_KEY = "GET_CONDUCTIVITY_INTERVAL_KEY";
	public final static String GET_WATER_LEVEL_MIN_KEY = "GET_WATER_LEVEL_MIN_KEY";
	public final static String GET_WATER_LEVEL_MAX_KEY = "GET_WATER_LEVEL_MAX_KEY";
	public final static String GET_WATER_LEVEL_INTERVAL_KEY = "GET_WATER_LEVEL_INTERVAL_KEY";
	public final static String ALARM_XML = "ALARM_XML";

	public final static int HANDLE_GET_PH_MIN = 0;
	public final static int HANDLE_GET_PH_MAX = 1;
	public final static int HANDLE_GET_TEMPERATURE_MIN = 2;
	public final static int HANDLE_GET_TEMPERATURE_MAX = 3;
	public final static int HANDLE_GET_OXYGEN_MIN = 4;
	public final static int HANDLE_GET_OXYGEN_MAX = 5;
	public final static int HANDLE_GET_CONDUCTIVITY_MIN = 6;
	public final static int HANDLE_GET_CONDUCTIVITY_MAX = 7;
	public final static int HANDLE_GET_WATER_LEVEL_MIN = 8;
	public final static int HANDLE_GET_WATER_LEVEL_MAX = 9;

	private float mPhMin;
	private float mPhMax;
	private float mTemperatureMin;
	private float mTemperatureMax;
	private float mOxygenMin;
	private float mOxygenMax;
	private float mConductivityMin;
	private float mConductivityMax;
	private float mWaterLevelMax;
	private float mWaterLevelMin;

	// private float mIsWaterLevelNormal;

	private long mPhAlarmInterval;
	private long mTemperatureAlarmInterval;
	private long mOxygenAlarmInterval;
	private long mConductivityAlarmInterval;
	private long mWaterLevelAlarmInterval;

	private static SharedPreferences mSharedPreferences;
	private SharedPreferences.Editor mEditor;
	private Context mContext;

	private static AlarmManager mAlarmManager;
	private RecvDataDispatcher mRecvDataDispatcher;

	private Handler mAlarmManagerHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case HANDLE_GET_PH_MIN:
				mPhMin = (Float) msg.obj;
				notifyGetData(GET_PH_MIN_KEY, String.valueOf(mPhMin));
				break;
			case HANDLE_GET_PH_MAX:
				mPhMax = (Float) msg.obj;
				notifyGetData(GET_PH_MAX_KEY, String.valueOf(mPhMax));
				break;
			case HANDLE_GET_TEMPERATURE_MIN:
				mTemperatureMin = (Float) msg.obj;
				notifyGetData(GET_TEMPERATURE_MIN_KEY,
						String.valueOf(mTemperatureMin));
				break;
			case HANDLE_GET_TEMPERATURE_MAX:
				mTemperatureMax = (Float) msg.obj;
				notifyGetData(GET_TEMPERATURE_MAX_KEY,
						String.valueOf(mTemperatureMax));
				break;
			case HANDLE_GET_OXYGEN_MIN:
				mOxygenMin = (Float) msg.obj;
				notifyGetData(GET_OXYGEN_MIN_KEY, String.valueOf(mOxygenMin));
				break;
			case HANDLE_GET_OXYGEN_MAX:
				mOxygenMax = (Float) msg.obj;
				notifyGetData(GET_OXYGEN_MAX_KEY, String.valueOf(mOxygenMax));
				break;
			case HANDLE_GET_CONDUCTIVITY_MIN:
				mConductivityMin = (Float) msg.obj;
				notifyGetData(GET_CONDUCTIVITY_MIN_KEY,
						String.valueOf(mConductivityMin));
				break;
			case HANDLE_GET_CONDUCTIVITY_MAX:
				mConductivityMax = (Float) msg.obj;
				notifyGetData(GET_CONDUCTIVITY_MAX_KEY,
						String.valueOf(mConductivityMax));
				break;
			case HANDLE_GET_WATER_LEVEL_MIN:
				mWaterLevelMin = (Float) msg.obj;
				notifyGetData(GET_WATER_LEVEL_MIN_KEY,
						String.valueOf(mWaterLevelMin));
				break;
			case HANDLE_GET_WATER_LEVEL_MAX:
				mWaterLevelMax = (Float) msg.obj;
				notifyGetData(GET_WATER_LEVEL_MAX_KEY,
						String.valueOf(mWaterLevelMax));
				break;
			default:
				break;
			}

		};
	};

	private AlarmManager() {
		mRecvDataDispatcher = RecvDataDispatcher.getInstance();
		mRecvDataDispatcher.setAlarmManagerHandler(mAlarmManagerHandler);
	}

	private AlarmManager(Context context) {
		mContext = context;
		mRecvDataDispatcher = RecvDataDispatcher.getInstance();
		mRecvDataDispatcher.setAlarmManagerHandler(mAlarmManagerHandler);
		mSharedPreferences = mContext.getSharedPreferences(ALARM_XML,
				Context.MODE_PRIVATE);
		mEditor = mSharedPreferences.edit();
		intitAllValue();
	}

	public static AlarmManager getInstance(Context context) {
		if (mAlarmManager == null || mSharedPreferences == null) {
			mAlarmManager = new AlarmManager(context);
		}
		return mAlarmManager;
	}

	public static AlarmManager getInstance() {
		if (mAlarmManager == null) {
			mAlarmManager = new AlarmManager();
		}
		return mAlarmManager;
	}

	private void intitAllValue() {
		mConductivityAlarmInterval = SPUtils.getSP(mSharedPreferences,
				GET_CONDUCTIVITY_INTERVAL_KEY,
				AlarmDefaultValue.INTERVALConductivity);
		mConductivityMax = SPUtils.getSP(mSharedPreferences,
				GET_CONDUCTIVITY_MAX_KEY, AlarmDefaultValue.MAXConductivity);
		mConductivityMin = SPUtils.getSP(mSharedPreferences,
				GET_CONDUCTIVITY_MIN_KEY, AlarmDefaultValue.MINConductivity);
		mOxygenAlarmInterval = SPUtils.getSP(mSharedPreferences,
				GET_OXYGEN_INTERVAL_KEY, AlarmDefaultValue.INTERVALOxygen);
		mOxygenMax = SPUtils.getSP(mSharedPreferences, GET_OXYGEN_MAX_KEY,
				AlarmDefaultValue.MAXOxygen);
		mOxygenMin = SPUtils.getSP(mSharedPreferences, GET_OXYGEN_MIN_KEY,
				AlarmDefaultValue.MINOxygen);
		mPhAlarmInterval = SPUtils.getSP(mSharedPreferences,
				GET_PH_INTERVAL_KEY, AlarmDefaultValue.INTERVALPH);
		mPhMax = SPUtils.getSP(mSharedPreferences, GET_PH_MAX_KEY,
				AlarmDefaultValue.MAXPH);
		mPhMin = SPUtils.getSP(mSharedPreferences, GET_PH_MIN_KEY,
				AlarmDefaultValue.MINPH);
		mTemperatureAlarmInterval = SPUtils.getSP(mSharedPreferences,
				GET_TEMPERATURE_INTERVAL_KEY,
				AlarmDefaultValue.INTERVALTEMPERATURE);
		mTemperatureMax = SPUtils.getSP(mSharedPreferences,
				GET_TEMPERATURE_MAX_KEY, AlarmDefaultValue.MAXTEMPERATURE);
		mTemperatureMin = SPUtils.getSP(mSharedPreferences,
				GET_TEMPERATURE_MIN_KEY, AlarmDefaultValue.MINTEMPERATURE);
		mWaterLevelAlarmInterval = SPUtils.getSP(mSharedPreferences,
				GET_WATER_LEVEL_INTERVAL_KEY,
				AlarmDefaultValue.INTERVALWATERLEVEL);
		mWaterLevelMax = SPUtils.getSP(mSharedPreferences,
				GET_WATER_LEVEL_MAX_KEY, AlarmDefaultValue.MAXWATERLEVEL);
		mWaterLevelMin = SPUtils.getSP(mSharedPreferences,
				GET_WATER_LEVEL_MIN_KEY, AlarmDefaultValue.MINWATERLEVEL);
	}

	public float getPhMin() {
		return mPhMin;
	}

	public void setPhMin(float mPhMin) {
		this.mPhMin = mPhMin;
		SPUtils.setSP(mEditor, GET_PH_MIN_KEY, mPhMin);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getPhMax() {
		return mPhMax;
	}

	public void setPhMax(float mPhMax) {
		this.mPhMax = mPhMax;
		SPUtils.setSP(mEditor, GET_PH_MAX_KEY, mPhMax);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getTemperatureMin() {
		return mTemperatureMin;
	}

	public void setTemperatureMin(float mTemperatureMin) {
		this.mTemperatureMin = mTemperatureMin;
		SPUtils.setSP(mEditor, GET_TEMPERATURE_MIN_KEY, mTemperatureMin);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getTemperatureMax() {
		return mTemperatureMax;
	}

	public void setTemperatureMax(float mTemperatureMax) {
		this.mTemperatureMax = mTemperatureMax;
		SPUtils.setSP(mEditor, GET_TEMPERATURE_MAX_KEY, mTemperatureMax);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getOxygenMin() {
		return mOxygenMin;
	}

	public void setOxygenMin(float mOxygenMin) {
		this.mOxygenMin = mOxygenMin;
		SPUtils.setSP(mEditor, GET_OXYGEN_MIN_KEY, mOxygenMin);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getOxygenMax() {
		return mOxygenMax;
	}

	public void setOxygenMax(float mOxygenMax) {
		this.mOxygenMax = mOxygenMax;
		SPUtils.setSP(mEditor, GET_OXYGEN_MAX_KEY, mOxygenMax);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getConductivityMin() {
		return mConductivityMin;
	}

	public void setConductivityMin(float mConductivityMin) {
		this.mConductivityMin = mConductivityMin;
		SPUtils.setSP(mEditor, GET_CONDUCTIVITY_MIN_KEY, mConductivityMin);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getConductivityMax() {
		return mConductivityMax;
	}

	public void setConductivityMax(float mConductivityMax) {
		this.mConductivityMax = mConductivityMax;
		SPUtils.setSP(mEditor, GET_CONDUCTIVITY_MAX_KEY, mConductivityMax);
		// TODO we need to composite a DataStruct and send to BTManage

	}

	public float getWaterLevelMax() {
		return mWaterLevelMax;
	}

	public void setWaterLevelMax(float mWaterLevelMax) {
		this.mWaterLevelMax = mWaterLevelMax;
		SPUtils.setSP(mEditor, GET_WATER_LEVEL_MAX_KEY, mWaterLevelMax);
	}

	public float getWaterLevelMin() {
		return mWaterLevelMin;
	}

	public void setWaterLevelMin(float mWaterLevelMin) {
		this.mWaterLevelMin = mWaterLevelMin;
		SPUtils.setSP(mEditor, GET_WATER_LEVEL_MAX_KEY, mWaterLevelMin);
	}

	public long getPhAlarmInterval() {
		return mPhAlarmInterval;
	}

	public long getTemperatureAlarmInterval() {
		return mTemperatureAlarmInterval;
	}

	public long getOxygenAlarmInterval() {
		return mOxygenAlarmInterval;
	}

	public long getConductivityAlarmInterval() {
		return mConductivityAlarmInterval;
	}

	public long getWaterLevelInterval() {
		return mWaterLevelAlarmInterval;
	}

	public void setPhAlarmInterval(long second) {
		mPhAlarmInterval = second;
		SPUtils.setSP(mEditor, GET_PH_INTERVAL_KEY, mPhAlarmInterval);
		// TODO use SP to store data
	}

	public void setTemperatureAlarmInterval(long second) {
		mTemperatureAlarmInterval = second;
		SPUtils.setSP(mEditor, GET_TEMPERATURE_INTERVAL_KEY,
				mTemperatureAlarmInterval);
		// TODO use SP to store data

	}

	public void setOxygenAlarmInterval(long second) {
		mOxygenAlarmInterval = second;
		SPUtils.setSP(mEditor, GET_OXYGEN_INTERVAL_KEY, mOxygenAlarmInterval);
		// TODO use SP to store data

	}

	public void setConductivityAlarmInterval(long second) {
		mConductivityAlarmInterval = second;
		SPUtils.setSP(mEditor, GET_CONDUCTIVITY_INTERVAL_KEY,
				mConductivityAlarmInterval);
		// TODO use SP to store data

	}

	public void setWaterLevelAlarmInterval(long second) {
		mWaterLevelAlarmInterval = second;
		SPUtils.setSP(mEditor, GET_WATER_LEVEL_INTERVAL_KEY,
				mConductivityAlarmInterval);
		// TODO use SP to store data

	}

	/**
	 * Set SMS number
	 * 
	 * @param num
	 *            The SMS number
	 */
	public void setSmsNumber(String num) {
		// TODO
	}

	/**
	 * Set E-mail address
	 * 
	 * @param address
	 *            The E-mail address
	 */
	public void setEmailAddres(String address) {
		// TODO
	}

	/**
	 * Do alarm
	 */
	public void alarm() {
		// TODO
	}

	/**
	 * Send SMS
	 */
	public void sendSms() {
		// TODO
	}

	/**
	 * Send E-mail
	 */
	public void sendEmail() {
		// TODO
	}

	/**
	 * Send data to Observers, such as {@link SensorValueDisplayActivity} and
	 * {@link LocalDataManager}
	 * 
	 * @param dataKey
	 * @param dataValue
	 */
	private void notifyGetData(String dataKey, String dataValue) {
		setChanged();
		HashMap<String, String> map = new HashMap<String, String>();
		map.put(dataKey, dataValue);
		notifyObservers(map);
	}

}
